ggplot2A universal framework that allows creating and combining without limits.
Almost.
Coordinates Geometries Scales Theme
Data Mapping Statistics Facets
dplyr/tidyr)ggplot2Multiplex CRISPR editing of wood for sustainable fiber production. Sulis DB, […], Barrangou R, Wang JP. 2023. Science 381:216–221. 10.1126/science.add4514
Three panels from main figure 3.
Arguments without default need to be supplied
Assign the function output of read_tsv("data/Sulis2023_fig3EF.tsv")
to the object sulis_bar_data.
# A tibble: 18 × 4
line replicate lignin CL
<chr> <dbl> <dbl> <dbl>
1 H-4 1 15.5 4.03
2 H-4 2 16.1 3.75
3 I-18 1 17.9 2.89
4 I-18 2 19.5 2.78
5 I-18 3 22.0 2.92
6 J-25 1 18.6 3.92
7 J-25 2 20.7 3.27
8 K-6 1 12.1 5.97
9 K-6 2 11.4 6.61
10 K-9 1 23.0 2.95
11 K-9 2 22.6 2.97
12 K-9 3 20.9 3.18
13 K-13 1 22.2 3.04
14 K-13 2 23.0 2.83
15 K-13 3 23.5 2.65
16 Wildtype 1 22.1 2.85
17 Wildtype 2 23.7 2.63
18 Wildtype 3 23.5 2.80
Figure from the paper.
Our first ggplot.
Which differences can you spot?
Layers are drawn in order, so before = below
Let’s not do that.
That didn’t work because the bar height is calculated within the function
after_stat(y) tells the function to use the y variable after calculation of the stats (in this case the mean)
library(ggtext)
panel_E <- ggplot(
data = sulis_bar_data,
aes(
x = fct_reorder(
line,
lignin,
.desc = TRUE
),
y = lignin
)
) +
scale_fill_distiller(
palette = "Greys"
) +
geom_bar(
aes(fill = ..y..),
stat = "summary",
fun = "mean",
colour = "black"
) +
geom_jitter(width = 0.1) +
labs(
x = NULL,
y = "<b>Lignin content</b> (% wt)"
) +
theme(
axis.title.y = element_markdown()
)
panel_Eggtext is a ggplot2 extension that implements HTML and markdown syntax within strings
panel_E <- ggplot(
data = sulis_bar_data,
aes(
x = fct_reorder(
line,
lignin,
.desc = TRUE
),
y = lignin
)
) +
scale_fill_distiller(
palette = "Greys"
) +
geom_bar(
aes(fill = ..y..),
stat = "summary",
fun = "mean",
colour = "black"
) +
geom_jitter(width = 0.1) +
labs(
x = NULL,
y = "<b>Lignin content</b> (% wt)"
) +
theme(
axis.title.y = element_markdown(),
axis.text.x = element_text(
angle = 90,
vjust = 0.5,
hjust = 1
)
)
panel_Epanel_E <- ggplot(
data = sulis_bar_data,
aes(
x = fct_reorder(
line,
lignin,
.desc = TRUE
),
y = lignin
)
) +
scale_fill_distiller(
palette = "Greys"
) +
geom_bar(
aes(fill = ..y..),
stat = "summary",
fun = "mean",
colour = "black"
) +
geom_jitter(width = 0.1) +
labs(
x = NULL,
y = "<b>Lignin content</b> (% wt)"
) +
theme(
axis.title.y = element_markdown(),
axis.text.x = element_text(
angle = 90,
vjust = 0.5,
hjust = 1
),
legend.position = "none"
)
panel_Epanel_E <- ggplot(
data = sulis_bar_data,
aes(
x = fct_reorder(
line,
lignin,
.desc = TRUE
),
y = lignin
)
) +
scale_fill_distiller(
palette = "Greys"
) +
geom_bar(
aes(fill = ..y..),
stat = "summary",
fun = "mean",
colour = "black",
width = 0.8
) +
geom_jitter(
width = 0.1,
shape = 21,
fill = "black",
colour = "white"
) +
labs(
x = NULL,
y = "<b>Lignin content</b> (% wt)"
) +
scale_y_continuous(
expand = expansion(
mult = c(0, 0.05)
)
) +
theme_sulis() +
theme(
axis.title.y = element_markdown(),
axis.text.x = element_text(
angle = 90,
vjust = 0.5,
hjust = 1
),
legend.position = "none"
)
panel_EApplying a theme_*() can completely change the look — see how to make your own in the exercise file
Figure from the paper.
Our first ggplot. Text for ants? We’ll fix that later.
panel_F <- ggplot(
data = sulis_bar_data,
aes(
x = fct_reorder(
line,
lignin,
.desc = TRUE
),
y = CL
)
) +
scale_fill_distiller(
palette = "Greys",
direction = 1
) +
geom_bar(
aes(fill = ..y..),
stat = "summary",
fun = "mean",
colour = "black",
width = 0.8
) +
geom_jitter(
width = 0.1,
shape = 21,
fill = "black",
colour = "white"
) +
labs(
x = NULL,
y = "<b>C/L ratio</b>"
) +
scale_y_continuous(
expand = expansion(
mult = c(0, 0.05)
)
) +
theme_sulis() +
theme(
axis.title.y = element_markdown(),
axis.text.x = element_text(
angle = 90,
vjust = 0.5,
hjust = 1
),
legend.position = "none"
)
panel_FMultiplex CRISPR editing of wood for sustainable fiber production. Sulis DB, […], Barrangou R, Wang JP. 2023. Science 381:216–221. 10.1126/science.add4514
Three panels from main figure 3.
panel_K <- ggplot(
data = sulis_scatter_data,
aes(
x = rel_lignin,
y = rel_volume
)
) +
geom_point(
aes(
colour = type,
fill = after_scale(
alpha(colour, 0.4)
)
),
shape = "circle filled"
) +
scale_colour_manual(
values = c("#275d95", "#d25952")
) +
theme_sulis() +
theme(
legend.position = c(0.25, 0.95),
legend.title = element_blank()
)
panel_Kpanel_K <- ggplot(
data = sulis_scatter_data,
aes(
x = rel_lignin,
y = rel_volume
)
) +
geom_hline(
yintercept = 100,
colour = "grey",
linetype = "dashed"
) +
geom_point(
aes(
colour = type,
fill = after_scale(alpha(colour, 0.4))
),
shape = "circle filled"
) +
scale_colour_manual(
values = c("#275d95", "#d25952")
) +
theme_sulis() +
theme(
legend.position = c(0.25, 0.95),
legend.title = element_blank()
)
panel_K Figure from the paper.
Our third ggplot.
# A tibble: 13 × 7
line replicate type label rel_lignin rel_CL rel_volume
<chr> <dbl> <chr> <chr> <dbl> <dbl> <dbl>
1 WT 1 Wildtype <NA> 103. 97.2 89.6
2 WT 2 Wildtype <NA> 99.6 100. 98.6
3 WT 3 Wildtype <NA> 97.9 102. 113.
4 H-4 1 CRISPR-edited lines H-4-1 67.0 146. 106.
5 H-4 2 CRISPR-edited lines H-4-2 69.9 136. 66.2
6 H-18 1 CRISPR-edited lines <NA> 70.8 150. 72.6
7 H-19 1 CRISPR-edited lines <NA> 89.3 105. 85.6
8 H-19 2 CRISPR-edited lines <NA> 87.6 101. 103.
9 H-19 3 CRISPR-edited lines <NA> 79.3 117. 63.2
10 H-19 4 CRISPR-edited lines <NA> 98.8 99.1 52.1
11 H-20 1 CRISPR-edited lines <NA> 95.5 111. 95.0
12 H-20 2 CRISPR-edited lines <NA> 79.8 128. 92.5
13 H-20 3 CRISPR-edited lines <NA> 85.3 130. 75.9
library(ggrepel)
panel_K <- ggplot(
data = sulis_scatter_data,
aes(
x = rel_lignin,
y = rel_volume
)
) +
geom_hline(
yintercept = 100,
colour = "grey",
linetype = "dashed"
) +
geom_point(
aes(
colour = type,
fill = after_scale(alpha(colour, 0.4))
),
shape = "circle filled"
) +
geom_label_repel(
aes(label = label),
) +
scale_colour_manual(
values = c("#275d95", "#d25952")
) +
labs(
x = "**Lignin content** (% of wildtype)",
y = "<b>Stem volume</b> (% of wildtype)"
) +
theme_sulis() +
theme(
axis.title.x = element_markdown(),
axis.title.y = element_markdown(),
legend.position = c(0.25, 0.95),
legend.title = element_blank()
)
panel_Kggrepel creates labels that automatically avoid overlapping
library(ggrepel)
panel_K <- ggplot(
data = sulis_scatter_data,
aes(
x = rel_lignin,
y = rel_volume
)
) +
geom_hline(
yintercept = 100,
colour = "grey",
linetype = "dashed"
) +
geom_point(
aes(
colour = type,
fill = after_scale(alpha(colour, 0.4))
),
shape = "circle filled"
) +
geom_label_repel(
aes(label = label),
size = 8
) +
scale_colour_manual(
values = c("#275d95", "#d25952")
) +
labs(
x = "**Lignin content** (% of wildtype)",
y = "<b>Stem volume</b> (% of wildtype)"
) +
theme_sulis() +
theme(
axis.title.x = element_markdown(),
axis.title.y = element_markdown(),
legend.position = c(0.25, 0.95),
legend.title = element_blank()
)
panel_KGeom_* size is defined in mm, theme elements in pt
ggtext_size <- 8 / (14 / 5)
library(ggrepel)
panel_K <- ggplot(
data = sulis_scatter_data,
aes(
x = rel_lignin,
y = rel_volume
)
) +
geom_hline(
yintercept = 100,
colour = "grey",
linetype = "dashed"
) +
geom_point(
aes(
colour = type,
fill = after_scale(alpha(colour, 0.4))
),
shape = "circle filled"
) +
geom_label_repel(
aes(label = label),
size = ggtext_size
) +
scale_colour_manual(
values = c("#275d95", "#d25952")
) +
labs(
x = "**Lignin content** (% of wildtype)",
y = "<b>Stem volume</b> (% of wildtype)"
) +
theme_sulis() +
theme(
axis.title.x = element_markdown(),
axis.title.y = element_markdown(),
legend.position = c(0.25, 0.95),
legend.title = element_blank()
)
panel_K14 to 5 is the ratio of pt to mm
ggtext_size <- 8 / (14 / 5)
library(ggrepel)
panel_K <- ggplot(
data = sulis_scatter_data,
aes(
x = rel_lignin,
y = rel_volume
)
) +
geom_hline(
yintercept = 100,
colour = "grey",
linetype = "dashed"
) +
geom_point(
aes(
colour = type,
fill = after_scale(alpha(colour, 0.4))
),
shape = "circle filled"
) +
geom_label_repel(
aes(label = label),
size = ggtext_size,
label.size = NA,
fill = rgb(1, 1, 1, 0.5),
min.segment.length = 0
) +
scale_colour_manual(
values = c("#275d95", "#d25952")
) +
labs(
x = "**Lignin content** (% of wildtype)",
y = "<b>Stem volume</b> (% of wildtype)"
) +
theme_sulis() +
theme(
axis.title.x = element_markdown(),
axis.title.y = element_markdown(),
legend.position = c(0.25, 0.95),
legend.title = element_blank()
)
panel_Kpatchwork automatically aligns plots into multi-panel figures
PDFs don’t lose resolution and are easily edited in Inkscape/Photoshop
ragg and its devices (agg_tiff, agg_jpeg, agg_png) improve raster graphics text rendering
Open up 2023_ggplot2_exercises.rmd and give it a try